package dbgorm

import (
	"errors"
	"sync"

	"gorm.io/gorm"
)

// 扩展结构体
type DB struct {
	*gorm.DB
}

// 缓存连接池
var _cache sync.Map = sync.Map{}

// 数据库连接详情信息
type OptionInfo struct {
	Alias    string      // 设置每次获取连接时的别名，即每次可以使用此别名进行获取数据库连接
	DSN      string      // 数据库连接的DSN信息
	Type     string      // 数据库连接，默认MySQL，可选值：mysql、sqlite、sqlserver
	DB       *DB         // 数据库连接
	Conf     gorm.Config // 数据库连接的配置项信息
	LogLevel int         // 日志记录等级，仅针对默认日志项
}

// 配置项连接
type Option func(c *OptionInfo)

// 数据库连接，默认采用mysql的方式进行连接
//
//	DSN	数据库连接的DSN字符串
//	opt	连接配置项
func Open(dsn string, opt ...Option) (*DB, error) {
	def := default_config
	def.DSN = dsn
	for i := 0; i < len(opt); i++ {
		opt[i](&def)
	}
	if def.Type == "" {
		def.Type = getType(def.DSN)
	}
	if v, ok := _cache.Load(cache_key(&def)); ok {
		temp := v.(*OptionInfo)
		return temp.DB, nil
	}
	// 进行数据库连接
	der, ext := _default_dervice[def.Type]
	if !ext {
		return nil, errors.New("数据库驱动 " + def.Type + " 不存在")
	}
	db, err := gorm.Open(der(def.DSN), &def.Conf)
	if err != nil {
		return nil, err
	}
	db.Use(&tryConnect{
		CacheKey: cache_key(&def),
	})
	// 进行数据库连接缓存
	def.DB = &DB{DB: db}
	_cache.Store(cache_key(&def), &def)
	return def.DB, nil
}
